package com.hanser.hancoder.controller;


import com.hanser.hancoder.annotation.AuthCheck;
import com.hanser.hancoder.common.BaseResponse;
import com.hanser.hancoder.common.DeleteRequest;
import com.hanser.hancoder.common.ResultUtils;
import com.hanser.hancoder.constant.UserConstant;
import com.hanser.hancoder.exception.ErrorCode;
import com.hanser.hancoder.exception.ThrowUtils;
import com.hanser.hancoder.model.dto.user.*;
import com.hanser.hancoder.model.entity.User;
import com.hanser.hancoder.model.vo.LoginUserVO;
import com.hanser.hancoder.model.vo.UserVO;
import com.hanser.hancoder.service.Impl.service.UserService;
import com.mybatisflex.core.paginate.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

import static com.hanser.hancoder.constant.UserConstant.ADMIN_ROLE;

/**
 * 用户 控制层。
 *
 * @author Hanserwei
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/user")
public class UserController {

    private final UserService userService;


    @PostMapping("/add")
    @Operation(description = "创建用户")
    @AuthCheck(mustRole = ADMIN_ROLE)
    public BaseResponse<Long> addUser(@RequestBody @Parameter(description = "添加用户请求") UserAddRequest userAddRequest) {
        return ResultUtils.success(userService.saveUser(userAddRequest));
    }

    /**
     * 根据主键删除用户。
     *
     * @param deleteRequest 用户删除请求
     * @return {@code true} 删除成功，{@code false} 删除失败
     */
    @PostMapping("/delete")
    @Operation(description = "根据主键删除用户")
    @AuthCheck(mustRole = ADMIN_ROLE)
    public BaseResponse<Boolean> deleteUser(@RequestBody @Parameter(description = "删除用户请求") DeleteRequest deleteRequest) {
        return ResultUtils.success(userService.deleteUser(deleteRequest));
    }


    /**
     * 根据主键获取用户。
     *
     * @param id 用户主键
     * @return 用户详情
     */
    @GetMapping("/get")
    @Operation(description = "根据主键获取用户")
    @AuthCheck(mustRole = ADMIN_ROLE)
    public BaseResponse<User> getUserById(@Parameter(description = "用户主键") Long id) {
        return ResultUtils.success(userService.getUserById(id));
    }


    /**
     * 用户注册。
     *
     * @param userRegisterRequest 用户注册信息
     * @return 注册结果
     */
    @PostMapping("/register")
    @Operation(description = "用户注册")
    public BaseResponse<Long> userRegister(@RequestBody @Parameter(description = "用户信息") UserRegisterRequest userRegisterRequest) {
        ThrowUtils.throwIf(userRegisterRequest == null, ErrorCode.PARAMS_ERROR, "参数为空");
        String userAccount = userRegisterRequest.getUserAccount();
        String userPassword = userRegisterRequest.getUserPassword();
        String checkPassword = userRegisterRequest.getCheckPassword();
        long res = userService.userRegister(userAccount, userPassword, checkPassword);
        return ResultUtils.success(res);
    }

    /**
     * 用户登录。
     *
     * @param userLoginRequest 用户登录信息
     * @param request          请求对象
     * @return 登录结果
     */
    @PostMapping("/login")
    @Operation(description = "用户登录")
    public BaseResponse<LoginUserVO> userLogin(@RequestBody @Parameter(description = "用户登录信息") UserLoginRequest userLoginRequest, @Parameter(description = "请求对象") HttpServletRequest request) {
        ThrowUtils.throwIf(userLoginRequest == null, ErrorCode.PARAMS_ERROR);
        String userAccount = userLoginRequest.getUserAccount();
        String userPassword = userLoginRequest.getUserPassword();
        LoginUserVO loginUserVO = userService.userLogin(userAccount, userPassword, request);
        return ResultUtils.success(loginUserVO);
    }

    /**
     * 获取当前登录用户。
     *
     * @param request 请求对象
     * @return 当前登录用户信息
     */
    @GetMapping("/get/login")
    @Operation(description = "获取当前登录用户")
    public BaseResponse<LoginUserVO> getLoginUser(@Parameter(description = "登录时的请求对象") HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        return ResultUtils.success(userService.getLoginUserVO(loginUser));
    }

    /**
     * 退出登录。
     *
     * @param request 退出登录请求对象
     * @return 退出登录结果
     */
    @PostMapping("/logout")
    @Operation(description = "用户退出登录")
    public BaseResponse<Boolean> userLogout(@Parameter(description = "退出登录请求对象") HttpServletRequest request) {
        ThrowUtils.throwIf(request == null, ErrorCode.PARAMS_ERROR);
        boolean result = userService.userLogout(request);
        return ResultUtils.success(result);
    }

    /**
     * 获取用户VO
     *
     * @param id 用户id
     * @return 当前登录用户
     */
    @GetMapping("/get/vo")
    @Operation(description = "获取用户VO")
    public BaseResponse<LoginUserVO> getUserVOById(@Parameter(description = "用户id") long id) {
        BaseResponse<User> result = getUserById(id);
        User user = result.getData();
        return ResultUtils.success(userService.getLoginUserVO(user));
    }

    /**
     * 更新用户
     *
     * @param userUpdateRequest 用户更新请求
     * @return 是否更新成功
     */
    @PostMapping("/update")
    @Operation(description = "更新用户")
    @AuthCheck(mustRole = ADMIN_ROLE)
    public BaseResponse<Boolean> updateUser(@RequestBody UserUpdateRequest userUpdateRequest) {
        return ResultUtils.success(userService.updateUser(userUpdateRequest));
    }

    @PostMapping("/update/userinfo")
    @Operation(description = "更新用户个人信息")
    public BaseResponse<Boolean> updateUserInfo(@RequestBody UserUpdateRequest userUpdateRequest) {
        return ResultUtils.success(userService.updateUser(userUpdateRequest));
    }


    /**
     * 分页获取用户封装列表（仅管理员）
     *
     * @param userQueryRequest 查询请求参数
     */
    @PostMapping("/list/page/vo")
    @Operation(description = "分页获取用户列表")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<UserVO>> listUserVOByPage(@RequestBody UserQueryRequest userQueryRequest) {
        ThrowUtils.throwIf(userQueryRequest == null, ErrorCode.PARAMS_ERROR);
        long pageNum = userQueryRequest.getPageNum();
        long pageSize = userQueryRequest.getPageSize();
        Page<User> userPage = userService.page(Page.of(pageNum, pageSize),
                userService.getQueryWrapper(userQueryRequest));
        // 数据脱敏
        Page<UserVO> userVOPage = new Page<>(pageNum, pageSize, userPage.getTotalRow());
        List<UserVO> userVOList = userService.getUserVOList(userPage.getRecords());
        userVOPage.setRecords(userVOList);
        return ResultUtils.success(userVOPage);
    }
}
